package com.castle.fortress.admin.flowable.form.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import com.castle.fortress.admin.flowable.form.entity.FlowableFormConfigEntity;
import com.castle.fortress.admin.flowable.form.mapper.FormAnalyzeDataMapper;
import com.castle.fortress.admin.flowable.form.service.FlowableFormAnalyzeDataService;
import com.castle.fortress.admin.flowable.form.service.FlowableFormConfigService;
import com.castle.fortress.admin.form.dto.ColConditionDto;
import com.castle.fortress.admin.form.enums.DbQueryEnum;
import com.castle.fortress.admin.form.service.FormModelService;
import com.castle.fortress.admin.message.sms.dto.ConfigSmsDto;
import com.castle.fortress.admin.message.sms.service.ConfigSmsService;
import com.castle.fortress.admin.message.sms.service.SmsService;
import com.castle.fortress.admin.utils.RedisUtils;
import com.castle.fortress.common.entity.RespBody;
import com.castle.fortress.common.enums.SmsPlatFormEnum;
import com.castle.fortress.common.enums.YesNoEnum;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.GlobalRespCode;
import com.castle.fortress.common.utils.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 流程业务表数据管理 服务类
 *
 * @author castle
 * @since 2022-11-07
 */
@Service
public class FlowableFormAnalyzeDataServiceImpl implements FlowableFormAnalyzeDataService {
    @Autowired
    private FormAnalyzeDataMapper formAnalyzeDataMapper;
    @Autowired
    private FormModelService formModelService;
    @Autowired
    private FlowableFormConfigService flowableFormConfigService;
    @Autowired
    private ConfigSmsService configSmsService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SmsService smsService;
    //验证码模板
    @Value("${castle.captcha.formCode}")
    private String smsCode;


    @Override
    public List<Map<String, Object>> queryAnalyzeListData(String formKey,Map<String,Object> queryMap) {
        FlowableFormConfigEntity configEntity = flowableFormConfigService.getById(formKey);
        String tbName = "castle_approve_form"+formKey;
        //校验表名是否存在
        if(configEntity==null || !formModelService.isExistTable(tbName)){
            throw new BizException(GlobalRespCode.UNAUTHORIZED);
        }
        //校验查询条件 参数合法且不为空
        List<Map<String, Object>> data = formAnalyzeDataMapper.queryAnalyzeListData(tbName,queryMap);
        return data;
    }

    @Override
    public Long queryAnalyzeCount(String formKey,Map<String,Object> queryMap) {
        String tbName = "castle_approve_form"+formKey;
        //校验查询条件 参数合法且不为空
        return formAnalyzeDataMapper.queryAnalyzeCount(tbName,queryMap);
    }

    @Override
    public Map<String, Object> queryAnalyzeInfoData(String formKey, String id) {
        FlowableFormConfigEntity configEntity = flowableFormConfigService.getById(formKey);
        String tbName = "castle_approve_form"+formKey;
        //校验表名是否存在
        if(configEntity==null || !formModelService.isExistTable(tbName)){
            throw new BizException(GlobalRespCode.UNAUTHORIZED);
        }
        return formAnalyzeDataMapper.queryAnalyzeInfo(tbName,id);
    }

    /**
     * 校验查询条件并初始化 参数合法且不为空
     * @param conditionConfig 条件配置
     * @param conditionJson 条件数据
     * @return
     */
    private List<ColConditionDto> initConditions(String conditionConfig,String conditionJson){
        List<ColConditionDto> conditions= new ArrayList<>();
        if(StrUtil.isEmpty(conditionConfig)||StrUtil.isEmpty(conditionJson)){
            return null;
        }
        try {
            //校验查询条件 参数合法且不为空
            conditions = new ArrayList<>();
            JSONArray configArray=new JSONArray(conditionConfig);
            if(StrUtil.isNotEmpty(conditionJson)){
                JSONObject obj=new JSONObject(conditionJson);
                for(String key:obj.keySet()){
                    if(obj.get(key)!=null&&StrUtil.isNotEmpty(obj.get(key).toString())){
                        ColConditionDto colConditionDto=new ColConditionDto();
                        colConditionDto.setColName(key);
                        for(int i=0;i<configArray.size();i++){
                            JSONObject o=configArray.getJSONObject(i);
                            if(o.getStr("model").equals(key)){
                                if(o.getBool("checked")&&StrUtil.isNotEmpty(o.getStr("queryType"))){
                                    colConditionDto.setConditionCode(o.getInt("queryType"));
                                    String conditionName = DbQueryEnum.getNameByCode(colConditionDto.getConditionCode());
                                    //校验查询方法是否支持
                                    if(StrUtil.isNotEmpty(conditionName)){
                                        colConditionDto.setConditionName(conditionName);
                                        String[] vs=obj.getStr(key).split("@;@");
                                        //校验查询字段值是否有效
                                        if(vs.length==0||StrUtil.isEmpty(vs[0])){
                                            break;
                                        }
                                        List<String> values=new ArrayList<>();
                                        //特殊处理的查询方法 like
                                        if(DbQueryEnum.LIKE.getCode().equals(colConditionDto.getConditionCode())) {
                                            values.add("%" + vs[0] + "%");
                                        }else if(DbQueryEnum.BETWEEN.getCode().equals(colConditionDto.getConditionCode())){
                                            values.add(vs[0]);
                                            values.add(vs[1]);
                                        }else{
                                            values.add(vs[0]);
                                        }
                                        colConditionDto.setValues(values.toArray());
                                        conditions.add(colConditionDto);
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }
        } catch (JSONException e) {
            return null;
        }
        return conditions.isEmpty()?null:conditions;
    }



    @Override
    public boolean getCode(Map<String, Object> map) {
        if(CommonUtil.verifyParamNull(map,map.get("tbId"),map.get("phone_sms"))){
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        String tbId = map.get("tbId").toString();
        String mobile = map.get("phone_sms").toString();
        //校验表名是否存在
        if(!formModelService.isExistTable("castle_approve_form"+tbId)){
            throw new BizException(GlobalRespCode.UNAUTHORIZED);
        }
        //获取短信模板
        ConfigSmsDto configSmsDto = new ConfigSmsDto();
        configSmsDto.setSmsCode(smsCode);
        configSmsDto.setStatus(YesNoEnum.YES.getCode());
        List<ConfigSmsDto> templates = configSmsService.listConfigSms(configSmsDto);
        if(templates==null || templates.size()!=1){
            throw new BizException(GlobalRespCode.DB_DATA_ERROR);
        }
        ConfigSmsDto template = templates.get(0);
        // 6位随机验证码
        String code = String.valueOf((int)(Math.random() * 1000000));
        String params = "";
        //阿里云模板 只支持 code参数
        if(SmsPlatFormEnum.ALIYUN.getCode().equals(template.getPlatform())){
            params="{\"code\":"+code+"}";
        }else if(SmsPlatFormEnum.TENCENTCLOUD.getCode().equals(template.getPlatform())){
            params=code;
        }else{
            throw new BizException(GlobalRespCode.DB_DATA_ERROR);
        }
        //获取配置有效期
        long expireTime = 5;
        FlowableFormConfigEntity configEntity = flowableFormConfigService.getById(tbId);
        JSONArray design=new JSONArray(configEntity.getDesignContent());
        for(int j=0;j<design.size();j++){
            JSONObject d=design.getJSONObject(j);
            String tag = d.getJSONObject("__config__").getStr("tag");
            String vModel = d.getStr("__vModel__");
            if(tag.equals("phone_sms")){
                expireTime = d.getJSONObject("__config__").getLong("validityMinute");
            }
        }
        String key = tbId+"_"+mobile;
        RespBody rb = smsService.send(smsCode,mobile,params);
        if(rb.isSuccess()){
            redisUtils.set(key,code,expireTime, TimeUnit.MINUTES);
            return true;
        }else{
            throw new BizException(rb.getMsg());
        }
    }

    @Override
    public boolean checkCode(String tbId,String mobile,String code) {
        String key = tbId+"_"+mobile;
        String value = redisUtils.get(key)==null?null:redisUtils.get(key).toString();
        if(value == null){
            throw new BizException(GlobalRespCode.CAPTCHA_EXPIRED_ERROR);
        }else if(!value.equals(code)){
            throw new BizException(GlobalRespCode.CAPTCHA_CODE_VERIFY_ERROR);
        }else{
            redisUtils.remove(key);
        }
        return true;
    }




}

